/**
 * =================================================================
 * 版权所有 2011-2013 深圳市泰海网络科技服务有限公司，并保留所有权利
 * -----------------------------------------------------------------
 * 这不是一个自由软件！您不能在任何未经允许的前提下对程序代码进行修改和使用；
 * 不允许对程序代码以任何形式任何目的的再发布
 * =================================================================
 */
package com.sfpay.api.internal.parser.json;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import com.sfpay.api.ApiException;
import com.sfpay.api.SfpayResponse;
import com.sfpay.api.internal.mapping.Converter;
import com.sfpay.api.internal.mapping.Converters;
import com.sfpay.api.internal.mapping.Reader;
import com.sfpay.api.internal.util.json.ExceptionErrorListener;
import com.sfpay.api.internal.util.json.JSONReader;
import com.sfpay.api.internal.util.json.JSONValidatingReader;

/**
 * 类说明：<br>
 * 
 * <p>
 * 详细描述：<br>
 * 
 * </p>
 * 
 * <pre>
 * ——————————————————————————————————————————————————————————————————
 * |		修改人		|		修改时间			|		修改原因
 * ——————————————————————————————————————————————————————————————————
 * |	zengxx 曾宪新	|		2013-8-18		|	
 * ——————————————————————————————————————————————————————————————————
 * </pre>
 * 
 * @author zengxx 曾宪新(Xavier.zeng)
 * 
 *         CreateDate: 2013-8-18
 */
public class JsonConverter implements Converter {
	
	@Override
	public <T extends SfpayResponse> T toResponse(String rsp, Class<T> clazz)
			throws ApiException {
		JSONReader reader = new JSONValidatingReader(
				new ExceptionErrorListener());
		Object rootObj = reader.read(rsp);
		if (rootObj instanceof Map<?, ?>) {
			Map<?, ?> rootJson = (Map<?, ?>) rootObj;
			Collection<?> values = rootJson.values();
			for (Object rspObj : values) {
				if (rspObj instanceof Map<?, ?>) {
					Map<?, ?> rspJson = (Map<?, ?>) rspObj;
					return fromJson(rspJson, clazz);
				}
			}
		}

		return null;
	}

	/**
	 * 方法说明：把JSON格式的数据转换为对象。
	 * 
	 * @param <T>
	 *            泛型领域对象
	 * @param json
	 *            JSON格式的数据
	 * @param clazz
	 *            泛型领域类型
	 * @return 领域对象
	 * @throws ApiException
	 */
	public <T> T fromJson(final Map<?, ?> json, Class<T> clazz)
			throws ApiException {
		return Converters.convert(clazz, new Reader() {
			@Override
			public boolean hasReturnField(Object name) {
				return json.containsKey(name);
			}

			@Override
			public Object getPrimitiveObject(Object name) {
				return json.get(name);
			}

			@Override
			public Object getObject(Object name, Class<?> type)
					throws ApiException {
				Object tmp = json.get(name);
				if (tmp instanceof Map<?, ?>) {
					Map<?, ?> map = (Map<?, ?>) tmp;
					return fromJson(map, type);
				} else {
					return null;
				}
			}

			@Override
			public List<?> getListObjects(Object listName, Object itemName,
					Class<?> subType) throws ApiException {
				List<Object> listObjs = null;

				Object listTmp = json.get(listName);
				if (listTmp instanceof Map<?, ?>) {
					Map<?, ?> jsonMap = (Map<?, ?>) listTmp;
					Object itemTmp = jsonMap.get(itemName);
					if (itemTmp == null && listName != null) {
						String listNameStr = listName.toString();
						itemTmp = jsonMap.get(listNameStr.substring(0,
								listNameStr.length() - 1));
					}
					if (itemTmp instanceof List<?>) {
						listObjs = new ArrayList<Object>();
						List<?> tmpList = (List<?>) itemTmp;
						for (Object subTmp : tmpList) {
							if (subTmp instanceof Map<?, ?>) {// object
								Map<?, ?> subMap = (Map<?, ?>) subTmp;
								Object subObj = fromJson(subMap, subType);
								if (subObj != null) {
									listObjs.add(subObj);
								}
							} else if (subTmp instanceof List<?>) {
								// array
							} else {
								// boolean, long, double, string, null
								listObjs.add(subTmp);
							}
						}
					}
				}

				return listObjs;
			}
		});
	}
}
